#!/bin/sh -e

RULES_FILE="/etc/udev/rules.d/82-persistent-cd.rules"

##############################################################################
lock_rules_file() {
  RULES_LOCK="/dev/.udev/.lock-${RULES_FILE##*/}"

  retry=30
  while ! mkdir $RULES_LOCK 2> /dev/null; do
    if [ $retry -eq 0 ]; then
       echo "Cannot lock $RULES_FILE!" >&2
       exit 2
    fi
    sleep 1
    retry=$(($retry - 1))
  done
}

unlock_rules_file() {
  rmdir $RULES_LOCK || true
}

##############################################################################
find_next_available() {
  # use echo to convert newlines to spaces
  local links=`echo $(find_all_symlinks $1)`
  local basename=${links%%[ 0-9]*}
  local max=-1
  for name in $links; do
    local num=${name#$basename}
    [ "$num" ] || num=0
    [ $num -gt $max ] && max=$num
  done

  max=$(($max + 1))
  # "name0" actually is just "name"
  [ $max -eq 0 ] && return
  echo "$max"
}

find_all_symlinks() {
  local linkre="$1"
  local match="$2"

  [ -e $RULES_FILE ] || return

  local search='.*[[:space:],]SYMLINK+="\('"$linkre"'\)"[[:space:]]*\(,.*\|\\\|\)$'

  sed -n -e "${match}s/${search}/\1/p" $RULES_FILE
}

write_rule() {
  local match="$1"
  local link="$2"
  local comment="$3"

  [ -e "$RULES_FILE" ] || PRINT_HEADER=1
  {
  if [ "$PRINT_HEADER" ]; then
    PRINT_HEADER=
    echo "# This file was automatically generated by the $0"
    echo "# program, probably run by the 83-cdrom.rules rules file."
    echo "#"
    echo "# You can modify it, as long as you keep each rule on a single line"
    echo "# and set the \$GENERATED variable."
    echo ""
  fi

  [ "$comment" ] && echo "# $comment"
  echo "ACTION==\"add\", SUBSYSTEM==\"block\", $match, ENV{ID_CDROM}==\"1\", SYMLINK+=\"$link\", ENV{GENERATED}=\"1\""
  } >> $RULES_FILE
  SYMLINKS="$SYMLINKS $link"
}

##############################################################################
if [ -z "$DEVPATH" ]; then
  echo "Missing \$DEVPATH." >&2
  exit 1
fi
if [ -z "$ID_CDROM" ]; then
  echo "$DEVPATH is not a CD reader." >&2
  exit 1
fi

# Prevent parallel processes from modifying the file at the same time.
lock_rules_file

link_num=$(find_next_available 'cdrom[0-9]*')

#match="ENV{ID_PATH}==\"$ID_PATH\""

#kernel=${DEVPATH##*/}
#match="KERNEL==\"$kernel\""

id=${PHYSDEVPATH##*/}
match="BUS==\"$PHYSDEVBUS\", ID==\"$id\""

comment="$ID_MODEL ($ID_PATH)"

			  write_rule "$match" "cdrom$link_num" "$comment"
[ "$ID_CDROM_CD_RW" ]  && write_rule "$match" "cdrw$link_num"
[ "$ID_CDROM_DVD" ]    && write_rule "$match" "dvd$link_num"
[ "$ID_CDROM_DVD_RW" ] && write_rule "$match" "dvdrw$link_num"

unlock_rules_file

echo $SYMLINKS

exit 0

